import pathlib
from . import juejin, jisilu
import pandas as pd
from datetime import datetime, time
from functools import partial


def combine_juejin_jsl(juejin_dir: pathlib.Path, jsl_dir: pathlib.Path,
                       start_date: str, freq: str):
    end_date = datetime.now().date()
    ins, bars = juejin.refresh_conbond(start_date, str(end_date), freq,
                                       juejin_dir)
    ins.drop(columns=['listed_date'], inplace=True)
    jsl_ins, _ = jisilu.refresh_now(jsl_dir, to_juejin=True)
    ins = ins.join(jsl_ins)

    # indicators from jisilu
    bars = bars.reset_index()
    dfs = []
    for dt in set(bars.datetime.dt.date.tolist()):
        fjsl = jsl_dir.joinpath('%s.csv' % dt)
        assert fjsl.exists(), dt
        """
        if not fjsl.exists():
            fjson = jsl_dir.joinpath('%s.json' % dt)
            assert fjson.exists(), dt
            import logging
            try:
                jisilu.refresh_now(jsl_dir, dt=dt)
            except Exception as e:
                logging.error(dt)
                continue
        """
        dfs.append(pd.read_csv(fjsl, parse_dates=['datetime']))
    indicators = pd.concat(dfs)
    # To be consistent with existing rq data
    indicators['remaining_size'] = indicators.remaining_size * 100000000
    indicators = indicators.rename(columns={
        'order_book_id': 'cb_id'
    },
        errors='raise').set_index(
        ['datetime', 'cb_id'])
    bars['cb_id'] = bars.order_book_id.apply(lambda obi: int(obi[5:]))
    bars.set_index(['datetime', 'cb_id'], inplace=True)
    bars = bars.join(indicators[[
        'conversion_value', 'yield_to_maturity', 'remaining_size',
        'double_low_factor', 'convert_premium_rate', 'call_qualified_days',
        'put_qualified_days'
    ]])
    bars = bars.reset_index().drop(columns=['cb_id']).sort_values(
        ['datetime', 'order_book_id']).set_index(['datetime', 'order_book_id'])
    return ins, bars


def conbond_backtest_data_fn(start_date: str, cache_dir: pathlib.Path):
    def get_backtest_data(instruments: pd.DataFrame, conbond_bars: pd.DataFrame,
                          context, _):
        dt = datetime.combine(context.now.date(), time(0, 0, 0))
        data = conbond_bars.loc[pd.IndexSlice[dt:dt, :]].join(instruments[[
            'bond_type', 'symbol', 'de_listed_date', 'listed_date'
        ]])
        data['increase_rt'] = data.close / data.open - 1
        return data

    jsl_dir = cache_dir.joinpath('jisilu')
    juejin_dir = cache_dir.joinpath('juejin')
    ins, bars = combine_juejin_jsl(juejin_dir, jsl_dir,
                                   start_date, '1d')
    return partial(get_backtest_data, ins, bars)
